package com.apes.framework.query.lib;

import com.apestech.framework.json.JSON;
import com.apestech.framework.json.JSONArray;
import com.apestech.framework.json.JSONObject;
import com.apestech.framework.sql.MakeCondition;

import java.util.ArrayList;
import java.util.Date;
import java.util.Map;

public class JPAInput {
    private boolean query;
    private JSONObject input;
    private JSONObject out;
    private String method;

    public JPAInput(JSONObject input){
        this.input=input;
        query=(input.get("queryId")!=null);
        method=input.getString("method");
        if(!query){
            query=(method.indexOf(".get")>=0 || method.indexOf("query")>=0);
        }
    }

    public JSONObject getData() throws Exception {
        out=new JSONObject();
        for(String k:input.getKeylist()){
            if(input.get(k)==null || "".equals(input.getString(k).trim())){
                continue;
            }
            Object value=input.get(k);
            if(k.indexOf("_DATE")>=0){
                setDate(k, value);
                continue;
            }
            if("condition".equals(k)){
                setCondition(value);
                continue;
            }
            if(value instanceof ArrayList){
                setArray(k, (ArrayList)value);
            } else if(value instanceof Map){
                setMap(k, JSON.toJSON(value));
            } else {
                out.put(k, value);
            }
        }
        return out;
    }

    private void setArray(String k, ArrayList list) throws Exception {
        int len=list.size();
        ArrayList<String> slist=new ArrayList<>();
        boolean flag=false;
        if(len>0){
            if(query){
                for(Object obj: list){
                    if(obj instanceof Map){ //1）为数值 2）联想字段查询 3）下拉字段的固定格式
                        if(len==1){
                            setMap(k, JSON.toJSON(obj));
                        } else {
                            String id=getIdValue(JSON.toJSON(obj));
                            if(id!=null){
                                slist.add(id);
                                flag=true;
                            } else {
                                setMap(k, JSON.toJSON(obj));
                            }
                        }
                    } else if(obj instanceof String){
                        out.put(k, list);
                        break;
                    }
                }
                if(flag){
                    out.put(k, slist);
                }
            } else {
                if(method.indexOf("save")>=0 || method.indexOf("strategy.exec")>=0){
                    out.put(k, list);
                } else {
                    for(Object obj: list) {
                        if (obj instanceof Map) {
                            if(!setMap(k, JSON.toJSON(obj))){
                                out.put(k, list);
                                break;
                            }
                        }
                    }
                }
            }
        }
    }

    private void setCondition(Object obj) throws Exception {
        if(obj instanceof Map){
            out.putAll((Map)obj);
            Object con=out.get("EXE_CONDITION");
            if(con!=null){
                if(con instanceof Map){
                    out.put("CID", ((Map)con).get("ID"));
                    con=out.get("EXE_DIMENSION");
                    out.put("MID", ((Map)con).get("ID"));
                } else {
                    out.put("CID", con);
                    out.put("MID", out.get("EXE_DIMENSION"));
                }
            }
        } else if (obj instanceof ArrayList){
            JSONArray list=new JSONArray();
            JSONArray vlist=JSON.toJSONArray(obj);
            int len=vlist.size();
            for(int i=0; i<len; i++){
                JSONObject map=vlist.get(i);
                String field=map.getString("field");
                if(field!=null){
                    String operator=map.getString("operator");
                    if("EQ".equals(operator) || "IN".equals(operator)){
                        if("EXE_CONDITION".equals(field)) {
                            out.put("CID", map.get("value"));
                        } if("EXE_DIMENSION".equals(field)) {
                            out.put("MID", map.get("value"));
                        } else {
                            out.put(field, map.get("value"));
                        }
                    } else {
                        list.add(map);
                    }
                }
            }
            if(list.size()>0){
                out.put("condition", list);
            }
        } else {
            out.put("condition", obj);
        }
    }

    private String getIdValue(JSONObject map){
        String id=map.getString("ID");
        if(id==null){
            id=map.getString("id");
        }
        return id;
    }

    private boolean setMap(String k, JSONObject map) throws Exception {
        boolean flag=false;
        String id=getIdValue(map);
        if(id!=null){
            if("EXE_CONDITION".equals(k)) {
                out.put("CID", id);
            } else if("EXE_DIMENSION".equals(k)) {
                out.put("MID", id);
            } else {
                if(map.size()>1 && method.indexOf("query")>=0){
                    if("condition.exec.query.stop".equals(input.getString("queryid"))){
                        if(map.get("ID")!=null){
                            out.put(k, map.get("ID"));
                        } else {
                            out.put(k, map.get("id"));
                        }

                    } else {
                        out.putAll(map);
                        if(out.get("EXE_CONDITION")!=null){
                            JSONObject con= new JSONObject((Map)out.get("EXE_CONDITION"));
                            JSONObject dim= new JSONObject((Map)out.get("EXE_DIMENSION"));
                            out.put("CID", con.getString("ID"));
                            out.put("MID", dim.getString("ID"));
                        }
                    }
                } else {
                    out.put(k, id);
                }

            }
            flag=true;
        } else {
            if(map.get("field")!=null){
                String f=map.getString("field");
                String v=map.getString("value");
                if(v!=null && !"".equals(v.trim())){
                    if("sysPurpose".equals(f)){
                        out.put("sysPurpose", v);
                    } else if("sysKey".equals(f)){
                        out.put("sysKey", v);
                    } else if("sysField".equals(f)){
                        out.put("sysField", v);
                    } else if("EXE_CONDITION".equals(f)) {
                        out.put("CID", v);
                    } else if("EXE_DIMENSION".equals(f)) {
                        out.put("MID", v);
                    } else if("sysform".equals(f)) {
                        out.put("sysform", v);
                    }
                }
                flag=true;
            } if(map.get("sysField")!=null){
                out.put("sysField", map.get("sysField"));
            } else {
                for(String key: map.getKeylist()){
                    Object value=map.get(key);
                    if(value instanceof Map){
                        setMap(key, JSON.toJSON(value));
                    } else if(value instanceof ArrayList){
                        setArray(key, (ArrayList)value);
//                    } else {
//                        out.put(key, value);
                    }
                }
            }
        }
        return flag;
    }

    private void setDate(String k, Object value){
        if(value instanceof String){
            out.put(k, value);
        } else if(value instanceof Date){
            out.put(k, value);
        } else  if(value instanceof ArrayList){
            ArrayList<String> list= (ArrayList<String>) value;
            if(list.size()==2){
                MakeCondition con=new MakeCondition();
                String k1=k;
                if(k.equals("START_DATE_Q")){
                    k1="START_DATE";
                } else if(k.equals("UPDATE_DATE_Q")){
                    k1="UPDATE_DATE";
                }
                con.addField(k1, "GTE", list.get(0), out);
                con.addField(k1, "LTE", list.get(1), out);
            } else {
                out.put(k, value);
            }
        }
    }

    private void setSysField(String k){  //联想字段查询

    }

    private void setQryCondition(){

    }

    private void setCondition(){  //策略查询

    }

}
